﻿using System;
using System.Collections.Generic;

/// <summary>
/// ONE THOUSAND.
/// </summary>
public sealed partial class OneThousand : IEquatable<OneThousand>, IComparable<OneThousand>, IConvertible
{
    /// <summary>
    /// ONE THOUSAND.
    /// </summary>
    private const int ONE_THOUSAND = 1000;

    /// <summary>
    /// Represents the value ONE THOUSAND.
    /// </summary>
    public static readonly OneThousand Value = new OneThousand();
    /// <summary>
    /// Represents the value ONE THOUSAND.
    /// </summary>
    public static readonly OneThousand MinValue = Value;
    /// <summary>
    /// Represents the value ONE THOUSAND.
    /// </summary>
    public static readonly OneThousand MaxValue = Value;

    /// <summary>
    /// Prevents a default instance of the <see cref="OneThousand"/> class from being created.
    /// </summary>
    private OneThousand()
    {
    }

    /// <summary>
    /// Us the int16.
    /// </summary>
    /// <param name="oneThousand">The one thousand.</param>
    /// <returns></returns>
    [CLSCompliant(false)]
    public static implicit operator ushort(OneThousand oneThousand)
    {
        return ONE_THOUSAND;
    }
    /// <summary>
    /// Int16s the specified one thousand.
    /// </summary>
    /// <param name="oneThousand">The one thousand.</param>
    /// <returns></returns>
    public static implicit operator short(OneThousand oneThousand)
    {
        return ONE_THOUSAND;
    }
    /// <summary>
    /// Us the int32.
    /// </summary>
    /// <param name="oneThousand">The one thousand.</param>
    /// <returns></returns>
    [CLSCompliant(false)]
    public static implicit operator uint(OneThousand oneThousand)
    {
        return ONE_THOUSAND;
    }
    /// <summary>
    /// Int32s the specified one thousand.
    /// </summary>
    /// <param name="oneThousand">The one thousand.</param>
    /// <returns></returns>
    public static implicit operator int(OneThousand oneThousand)
    {
        return ONE_THOUSAND;
    }
    /// <summary>
    /// Int64s the specified one thousand.
    /// </summary>
    /// <param name="oneThousand">The one thousand.</param>
    /// <returns></returns>
    public static implicit operator long(OneThousand oneThousand)
    {
        return ONE_THOUSAND;
    }
    /// <summary>
    /// Us the int64.
    /// </summary>
    /// <param name="oneThousand">The one thousand.</param>
    /// <returns></returns>
    [CLSCompliant(false)]
    public static implicit operator ulong(OneThousand oneThousand)
    {
        return ONE_THOUSAND;
    }
    /// <summary>
    /// Singles the specified one thousand.
    /// </summary>
    /// <param name="oneThousand">The one thousand.</param>
    /// <returns></returns>
    public static implicit operator float(OneThousand oneThousand)
    {
        return ONE_THOUSAND;
    }
    /// <summary>
    /// Doubles the specified one thousand.
    /// </summary>
    /// <param name="oneThousand">The one thousand.</param>
    /// <returns></returns>
    public static implicit operator double(OneThousand oneThousand)
    {
        return ONE_THOUSAND;
    }
    /// <summary>
    /// Decimals the specified one thousand.
    /// </summary>
    /// <param name="oneThousand">The one thousand.</param>
    /// <returns></returns>
    public static implicit operator decimal(OneThousand oneThousand)
    {
        return ONE_THOUSAND;
    }

    /// <summary>
    /// Called when [thousand].
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    /// <exception cref="System.InvalidCastException">Value is not ONE THOUSAND.</exception>
    public static explicit operator OneThousand(long value)
    {
        if (value != ONE_THOUSAND)
            throw new InvalidCastException("Value is not ONE THOUSAND.");

        return OneThousand.Value;
    }
    /// <summary>
    /// Called when [thousand].
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    /// <exception cref="System.InvalidCastException">Value is not ONE THOUSAND.</exception>
    [CLSCompliant(false)]
    public static explicit operator OneThousand(ulong value)
    {
        if (value != ONE_THOUSAND)
            throw new InvalidCastException("Value is not ONE THOUSAND.");

        return OneThousand.Value;
    }
    /// <summary>
    /// Called when [thousand].
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    /// <exception cref="System.InvalidCastException">Value is not ONE THOUSAND.</exception>
    public static explicit operator OneThousand(int value)
    {
        if (value != ONE_THOUSAND)
            throw new InvalidCastException("Value is not ONE THOUSAND.");

        return OneThousand.Value;
    }
    /// <summary>
    /// Called when [thousand].
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    /// <exception cref="System.InvalidCastException">Value is not ONE THOUSAND.</exception>
    [CLSCompliant(false)]
    public static explicit operator OneThousand(uint value)
    {
        if (value != ONE_THOUSAND)
            throw new InvalidCastException("Value is not ONE THOUSAND.");

        return OneThousand.Value;
    }
    /// <summary>
    /// Called when [thousand].
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    /// <exception cref="System.InvalidCastException">Value is not ONE THOUSAND.</exception>
    public static explicit operator OneThousand(short value)
    {
        if (value != ONE_THOUSAND)
            throw new InvalidCastException("Value is not ONE THOUSAND.");

        return OneThousand.Value;
    }
    /// <summary>
    /// Called when [thousand].
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    /// <exception cref="System.InvalidCastException">Value is not ONE THOUSAND.</exception>
    [CLSCompliant(false)]
    public static explicit operator OneThousand(ushort value)
    {
        if (value != ONE_THOUSAND)
            throw new InvalidCastException("Value is not ONE THOUSAND.");

        return OneThousand.Value;
    }
    /// <summary>
    /// Called when [thousand].
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    /// <exception cref="System.InvalidCastException">Value is not ONE THOUSAND.</exception>
    public static explicit operator OneThousand(float value)
    {
        if (value != ONE_THOUSAND)
            throw new InvalidCastException("Value is not ONE THOUSAND.");

        return OneThousand.Value;
    }
    /// <summary>
    /// Called when [thousand].
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    /// <exception cref="System.InvalidCastException">Value is not ONE THOUSAND.</exception>
    public static explicit operator OneThousand(double value)
    {
        if (value != ONE_THOUSAND)
            throw new InvalidCastException("Value is not ONE THOUSAND.");

        return OneThousand.Value;
    }
    /// <summary>
    /// Called when [thousand].
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    /// <exception cref="System.InvalidCastException">Value is not ONE THOUSAND.</exception>
    public static explicit operator OneThousand(decimal value)
    {
        if (value != ONE_THOUSAND)
            throw new InvalidCastException("Value is not ONE THOUSAND.");

        return OneThousand.Value;
    }

    /// <summary>
    /// Returns an array of ONE THOUSAND elements.
    /// </summary>
    /// <typeparam name="T">Type of the elements.</typeparam>
    /// <returns>Array of ONE THOUSAND elements.</returns>
    public static T[] Array<T>()
    {
        return new T[ONE_THOUSAND];
    }
    /// <summary>
    /// Returns ONE THOUSAND copies of a value.
    /// </summary>
    /// <typeparam name="T">Type of the value.</typeparam>
    /// <param name="value">Value to thousandize.</param>
    /// <returns>ONE THOUSAND copies of the value.</returns>
    public static IEnumerable<T> Thousandize<T>(T value)
    {
        for (int i = 0; i < ONE_THOUSAND; i++)
            yield return value;
    }
    /// <summary>
    /// Returns ONE THOUSAND instances of a type.
    /// </summary>
    /// <typeparam name="T">Type of the value.</typeparam>
    /// <returns>ONE THOUSAND instances of the type.</returns>
    public static IEnumerable<T> Thousandize<T>()
        where T : new()
    {
        for (int i = 0; i < ONE_THOUSAND; i++)
            yield return new T();
    }
    /// <summary>
    /// Returns ONE THOUSAND instances of a type.
    /// </summary>
    /// <typeparam name="T">Type of the value.</typeparam>
    /// <param name="valueFactory">Method which produces a new instance.</param>
    /// <returns>ONE THOUSAND instances of the type.</returns>
    public static IEnumerable<T> Thousandize<T>(Func<T> valueFactory)
    {
        if (valueFactory == null)
            throw new ArgumentNullException("valueFactory");

        for (int i = 0; i < ONE_THOUSAND; i++)
            yield return valueFactory();
    }
    /// <summary>
    /// Converts a string to a ONE THOUSAND instance.
    /// </summary>
    /// <param name="s">String to parse to ONE THOUSAND.</param>
    /// <returns>Parsed value of ONE THOUSAND.</returns>
    public static OneThousand Parse(string s)
    {
        if (s == null)
            throw new ArgumentNullException("s");

        int value;
        int.TryParse(s, out value);
        if (value != ONE_THOUSAND)
            throw new ArgumentException("Value is not ONE THOUSAND.", "s");

        return OneThousand.Value;
    }
    /// <summary>
    /// Returns the ONE THOUSAND value of the specified type.
    /// </summary>
    /// <typeparam name="T">The type.</typeparam>
    /// <returns>The type's ONE THOUSAND value.</returns>
    [CLSCompliant(false)]
    public static T ThousandValue<T>()
        where T : IConvertible
    {
        return (T)Convert.ChangeType(ONE_THOUSAND, typeof(T), System.Globalization.CultureInfo.CurrentCulture);
    }

    /// <summary>
    /// Compares the current object with another object of the same type.
    /// </summary>
    /// <param name="other">An object to compare with this object.</param>
    /// <returns>
    /// A 32-bit signed integer that indicates the relative order of the objects being compared. The return value has the following meanings:
    /// Value
    /// Meaning
    /// Less than zero
    /// This object is less than the <paramref name="other" /> parameter.
    /// Zero
    /// This object is equal to <paramref name="other" />.
    /// Greater than zero
    /// This object is greater than <paramref name="other" />.
    /// </returns>
    public int CompareTo(OneThousand other)
    {
        return other != null ? 0 : 1;
    }
    /// <summary>
    /// Indicates whether the current object is equal to another object of the same type.
    /// </summary>
    /// <param name="other">An object to compare with this object.</param>
    /// <returns>
    /// true if the current object is equal to the <paramref name="other" /> parameter; otherwise, false.
    /// </returns>
    public bool Equals(OneThousand other)
    {
        return other != null;
    }
    /// <summary>
    /// Determines whether the specified <see cref="System.Object" /> is equal to this instance.
    /// </summary>
    /// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param>
    /// <returns>
    ///   <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.
    /// </returns>
    public override bool Equals(object obj)
    {
        return this.Equals(obj as OneThousand);
    }
    /// <summary>
    /// Returns a hash code for this instance.
    /// </summary>
    /// <returns>
    /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
    /// </returns>
    public override int GetHashCode()
    {
        return ONE_THOUSAND;
    }
    /// <summary>
    /// Returns a <see cref="System.String" /> that represents this instance.
    /// </summary>
    /// <returns>
    /// A <see cref="System.String" /> that represents this instance.
    /// </returns>
    public override string ToString()
    {
        return ONE_THOUSAND.ToString();
    }
    /// <summary>
    /// Returns a <see cref="System.String" /> that represents this instance.
    /// </summary>
    /// <param name="provider">The provider.</param>
    /// <returns>
    /// A <see cref="System.String" /> that represents this instance.
    /// </returns>
    public string ToString(IFormatProvider provider)
    {
        return ONE_THOUSAND.ToString(provider);
    }
    /// <summary>
    /// Returns a <see cref="System.String" /> that represents this instance.
    /// </summary>
    /// <param name="format">The format.</param>
    /// <returns>
    /// A <see cref="System.String" /> that represents this instance.
    /// </returns>
    public string ToString(string format)
    {
        return ONE_THOUSAND.ToString(format);
    }
    /// <summary>
    /// Returns a <see cref="System.String" /> that represents this instance.
    /// </summary>
    /// <param name="format">The format.</param>
    /// <param name="provider">The provider.</param>
    /// <returns>
    /// A <see cref="System.String" /> that represents this instance.
    /// </returns>
    public string ToString(string format, IFormatProvider provider)
    {
        return ONE_THOUSAND.ToString(format, provider);
    }

    TypeCode IConvertible.GetTypeCode()
    {
        return TypeCode.Object;
    }
    bool IConvertible.ToBoolean(IFormatProvider provider)
    {
        throw new NotSupportedException();
    }
    byte IConvertible.ToByte(IFormatProvider provider)
    {
        throw new NotSupportedException();
    }
    char IConvertible.ToChar(IFormatProvider provider)
    {
        throw new NotSupportedException();
    }
    DateTime IConvertible.ToDateTime(IFormatProvider provider)
    {
        throw new NotSupportedException();
    }
    decimal IConvertible.ToDecimal(IFormatProvider provider)
    {
        return this;
    }
    double IConvertible.ToDouble(IFormatProvider provider)
    {
        return this;
    }
    short IConvertible.ToInt16(IFormatProvider provider)
    {
        return this;
    }
    int IConvertible.ToInt32(IFormatProvider provider)
    {
        return this;
    }
    long IConvertible.ToInt64(IFormatProvider provider)
    {
        return this;
    }
    sbyte IConvertible.ToSByte(IFormatProvider provider)
    {
        throw new NotSupportedException();
    }
    float IConvertible.ToSingle(IFormatProvider provider)
    {
        return this;
    }
    string IConvertible.ToString(IFormatProvider provider)
    {
        return this.ToString(provider);
    }
    object IConvertible.ToType(Type conversionType, IFormatProvider provider)
    {
        return Convert.ChangeType(ONE_THOUSAND, conversionType, System.Globalization.CultureInfo.CurrentCulture);
    }
    ushort IConvertible.ToUInt16(IFormatProvider provider)
    {
        return this;
    }
    uint IConvertible.ToUInt32(IFormatProvider provider)
    {
        return this;
    }
    ulong IConvertible.ToUInt64(IFormatProvider provider)
    {
        return this;
    }
}
